package FCRendering;

import FCRendering.azer.PlayerAction;
import FCRendering.sw.FCRListen;
import FCRendering.sw.FCRValues;
import Frame.screen.*;
import Function.*;
import VWorldGameStudio.*;
import VWorldGameStudio.events.BattleEvent;
import VWorldGameStudio.events.DoorEvent;
import VWorldGameStudio.events.JumpEvent;
import VWorldGameStudio.events.ShopEvent;
import VWorldGameStudio.touzi.BaiShuDIProject;
import VWorldGameStudio.touzi.BoBuSchoolProject;
import VWorldGameStudio.touzi.BoBuShaTanProject;
import VWorldGameStudio.touzi.FCTouZiProject;
import interfaces.IPlayerSlideCallback;
import io.reactivex.schedulers.Schedulers;
import lombok.Getter;
import lombok.Setter;
import org.omg.PortableServer.LIFESPAN_POLICY_ID;
import socket.FCRSocketClient;
import socket.FCRSocketServer;
import utils.ClickHelper;
import utils.FCDataSingles;
import utils.FCExGlobalConfigUtil;
import utils.FCUIConfig;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.Timer;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

import static FCRendering.FCRConstants.DEBUG_MODE;

public class FCRMaster extends JPanel {

    @Getter
    private String vwordg = "V-World Game Studio 2021 重制";


    @Getter
    private Font font;

    @Getter
    public static FCLanguageLibrary langLib = new FCLanguageLibrary();
    // 存档
    public static JTextField playerName = new JTextField();// 玩家名称
    public static FCSave gameSave = new FCSave();// 玩家当前游戏存档
    public static FCSaveLibrary saveList = new FCSaveLibrary();
    // 玩家信息
    public static FCPlayerInfo player1 = new FCPlayerInfo();// 玩家1信息

    // 素材
    public static FCCharacterLibrary charLib = new FCCharacterLibrary();
    public static FCBlockLibrary blockLib = new FCBlockLibrary();
    public static FCMapLibrary mapLib = new FCMapLibrary();
    public static FCEventLibrary eventLib = new FCEventLibrary();
    public static FCActionLibrary actionLib = new FCActionLibrary();
    public static FCMonsterLibrary monLib = new FCMonsterLibrary();
    public static FCAnimationLibrary animationLib = new FCAnimationLibrary();
    public static FCItemLibrary itemLib = new FCItemLibrary();
    public static FCPlotLibrary plotLib = new FCPlotLibrary();
    public static FCTankLibrary tankLib = new FCTankLibrary();
    public static FCMapAnimationLibrary mapAnimationLibrary = new FCMapAnimationLibrary();
    // ͨ联机类
    public static FCSocket socket = new FCSocket();
    public static JTextField playerbIp = new JTextField(FCRConstants.PLAYER_B_IP);
    public static JTextField playerbPort = new JTextField(FCRConstants.PLAYER_B_PORT);
    // 聊天消息
    @Getter
    private Font fon1;
    public static JTextField messageText;
    public static FCSound sound = new FCSound();
    // 剧情事件检测数据
    private FCPlotDetect plot;

    @Getter
    private int plotstep1 = -1;// 当前步骤
    @Getter
    private String plotnpc1sayname;// 当前说话的npcid
    @Setter
    @Getter
    private String plotnpc1sayid;// 当前npc说话的id


    @Getter
    private int plotstep2 = -1;// 当前步骤
    @Getter
    private String plotnpc2sayname;
    @Getter
    private String plotnpc2sayid;
    @Getter
    private boolean plotnpc2sayisclick = false;
    @Setter
    @Getter
    private boolean plotisjumstep2 = false;
    @Setter
    @Getter
    private Vector<String> plotnpc1 = new Vector<>();// 剧情中的npc
    @Setter
    @Getter
    private Vector<String> plotnpc2 = new Vector<>();

    @Getter
    private HashMap<String, Integer> plotnpc1face = new HashMap<>();// 剧情中的npc面向
    @Getter
    private HashMap<String, Integer> plotnpc2face = new HashMap<>();
    @Getter
    private HashMap<String, Integer[]> plotnpc1suozai = new HashMap<>();
    @Getter
    private HashMap<String, Integer[]> plotnpc2suozai = new HashMap<>();
    @Getter
    private HashMap<String, Integer[]> plotnpc1mubiao = new HashMap<>();
    @Getter
    private HashMap<String, Integer[]> plotnpc2mubiao = new HashMap<>();
    @Getter
    private HashMap<String, Integer[]> plotnpc1pianyi = new HashMap<>();// npc行走的偏移量
    @Getter
    private HashMap<String, Integer[]> plotnpc2pianyi = new HashMap<>();// npc行走的偏移量
    @Getter
    private HashMap<String, Integer> plotnpc1active = new HashMap<>();// npc当前动作编号
    @Getter
    private HashMap<String, Integer> plotnpcGoSpeed = new HashMap<>();// npc行走速度
    @Getter
    private HashMap<String, Integer> plotnpc2active = new HashMap<>();// npc当前动作编号
    // 开关门信息记录
    @Setter
    @Getter
    private boolean isplayopendoormusic = false;


    // 游戏按键信息
    public static FCHotKey hotkey = new FCHotKey();
    // 游戏时间信息
    public static FCDate gamedate = new FCDate();
    @Getter
    private FCBlack gameblack = new FCBlack();

    @Getter
    @Setter
    private int opendoorx = -1;
    @Getter
    @Setter
    private int opendoory = -1;


    public static FCRMaster fcrMaster;
    /**
     * 键鼠监听与变量参数库
     *
     * @date 2021-12-27
     */
    public static FCRListen fcl = new FCRListen();
    public static FCRValues fcv = new FCRValues();

    @Getter
    @Setter
    private IPlayerSlideCallback playerSlideCallback;

    private DefaultMapScreen defaultMapScreen = new DefaultMapScreen();//非战斗地图（行走，剧情等）
    public static DefaultFightScreen defaultFightScreen = new DefaultFightScreen();//纯战斗界面
    private DefaultInfoScreen defaultInfoScreen = new DefaultInfoScreen();// 渲染菜单、信息等窗口
    private DefaultMenuScreen defaultMenuScreen = new DefaultMenuScreen();// 渲染菜单
    private DefaultItemScreen defaultItemScreen = new DefaultItemScreen();// 渲染背包物品
    private DefaultMessageScreen defaultMessageScreen = new DefaultMessageScreen();// 消息
    private DefaultJumpactionAnimScreen defaultJumpactionAnimScreen = new DefaultJumpactionAnimScreen();// 跳转动画
    private DefaultHomeScreen defaultHomeScreen = new DefaultHomeScreen();//主菜单界面
    private DefaultSingleReadyScreen singlePlayerReadyScreen = new DefaultSingleReadyScreen(false);//单人准备界面
    private DefaultLoadingResScreen loadingResScreen = new DefaultLoadingResScreen();//加载资源界面
    private DefaultSingleReadyScreen newRoomScreen = new DefaultSingleReadyScreen(true);//多人开房界面
    private DefaultMultiFindRoomScreen findRoomScreen = new DefaultMultiFindRoomScreen();//多人找房界面
    private DefaultHelpToolScreen helpToolScreen = new DefaultHelpToolScreen();//全局工具打印调试的窗口
    private DefaultBoxOpenScreen boxOpenScreen = new DefaultBoxOpenScreen();//渲染箱子打开的和拖拉箱子物品的
    private DefaultTeamRequestScreen requestScreen = new DefaultTeamRequestScreen();//组队申请的
    private DefaultTimeScreen timeScreen = new DefaultTimeScreen();

    private FCMonsterBattleOrderHelper monsterBattleOrderHelper = new FCMonsterBattleOrderHelper();
    private FCPlayerBattleOrderHelper playerBattleOrderHelper = new FCPlayerBattleOrderHelper();
    private FilghtBattleMouseScreen mouseScreen = new FilghtBattleMouseScreen();

    /**
     * 和getInterfacenum 对应key值
     */
    private HashMap<Integer, IScreen> screenMaps = new HashMap<>();
    public FCMonsterBuildCoor fcMonsterBuildCoor;
    public static FCBattleEventOrderHelper eventOrderHelper = new FCBattleEventOrderHelper();
    PlayerAction playerAction = PlayerAction.getInstance();
    FCAutoTriggerEventHelper autoTriggerEventHelper = new FCAutoTriggerEventHelper();
    Object mLock = new Object();

    public FCRMaster() {
        try {
            fcrMaster = this;
            //初始化screen
            defaultMapScreen.addChildScreenByOrder(new ShopVedingScreen());
            defaultMapScreen.addChildScreenByOrder(new PhonographScreen());
            defaultMapScreen.addChildScreenByOrder(new OptionalSayScreen());
            defaultMapScreen.addChildScreenByOrder(new UseItemScreen());
            defaultMapScreen.addChildScreenByOrder(new PlotNpcSayScreen());
            defaultMapScreen.addChildScreenByOrder(new UseTankMenuScreen());
            defaultMapScreen.addChildScreenByOrder(new ChuanZhenListScreen());
            defaultMapScreen.addChildScreenByOrder(defaultInfoScreen);
            defaultMapScreen.addChildScreenByOrder(new WorldMapScreen());
            defaultMapScreen.addChildScreenByOrder(defaultMenuScreen);
            defaultMapScreen.addChildScreenByOrder(boxOpenScreen);
            defaultMapScreen.addChildScreenByOrder(defaultItemScreen);
            defaultMapScreen.addChildScreenByOrder(defaultMessageScreen);
            defaultMapScreen.addChildScreenByOrder(requestScreen);
            defaultMapScreen.addChildScreenByOrder(timeScreen);
            defaultMapScreen.addChildScreenByOrder(defaultJumpactionAnimScreen);
            //战斗的
            defaultFightScreen.addChildScreenByOrder(defaultInfoScreen);
            defaultFightScreen.addChildScreenByOrder(defaultMenuScreen);
            defaultFightScreen.addChildScreenByOrder(defaultItemScreen);
            defaultFightScreen.addChildScreenByOrder(defaultMessageScreen);
            defaultFightScreen.addChildScreenByOrder(mouseScreen);
            defaultFightScreen.addChildScreenByOrder(defaultJumpactionAnimScreen);

            screenMaps.put(0, defaultHomeScreen);
            screenMaps.put(1, singlePlayerReadyScreen);
            screenMaps.put(2, newRoomScreen);
            screenMaps.put(3, findRoomScreen);
            screenMaps.put(4, loadingResScreen);

            fcl.addIRListener(0, defaultHomeScreen);
            fcl.addIRListener(1, singlePlayerReadyScreen);
            fcl.addIRListener(2, newRoomScreen);
            fcl.addIRListener(3, findRoomScreen);
            fcl.addIRListener(5, new GameRunningRListener());
            fcl.addIRListener(6, defaultFightScreen);
            sound.setBackgroundMusic(0);

            FCExGlobalConfigUtil.getIn().parseConfigFile();
            FCUIConfig.getIn().parseConfigFile();//解析excel文本

            Timer timer = new Timer();
            timer.schedule(new updataUI(), new Date(), 16);
            timer = new Timer();
            timer.schedule(new MoveAction(), new Date(), 24);
            timer = new Timer();//每个计算都单独线程了
            timer.schedule(new battleAnimationData(), new Date(), 16);
            timer = new Timer();//每个计算都单独线程了
            timer.schedule(new touchoffplot(), new Date(), 20);
            timer.schedule(new plotnpcactive(), new Date(), 16);

            this.setLayout(null);

            fcv.setNowWindowWidth(getWidth());
            fcv.setNowWindowHeight(getHeight());

            playerName.setFont(new Font(FCRConstants.FONT_BLACK, 0, 24));
            playerName.setForeground(Color.white);
            playerName.setVisible(false);
            playerName.setOpaque(false);
            playerName.setBorder(BorderFactory.createLineBorder(Color.black));
            playerName.setCaretColor(Color.white);
            this.add(playerName);

            playerName.addKeyListener(new KeyListener() {
                @Override
                public void keyTyped(KeyEvent e) {
                }

                @Override
                public void keyReleased(KeyEvent e) {
                    fcl.listen_key_release_playername(playerName);
                }

                @Override
                public void keyPressed(KeyEvent e) {
                }
            });
            addMouseMotionListener(new MouseMotionListener() {
                @Override
                public void mouseMoved(MouseEvent g) {
                    fcl.listen_mouse_move_game(g);
                }

                @Override
                public void mouseDragged(MouseEvent g) {
                    fcv.setMouseX(g.getX());
                    fcv.setMouseY(g.getY());
                }
            });
            addMouseListener(new MouseListener() {
                @Override
                public void mouseReleased(MouseEvent g) {
                    fcl.listen_mouse_release_game(g);
                }

                @Override
                public void mousePressed(MouseEvent g) {
                    fcl.listen_mouse_press_game(g);
                }

                @Override
                public void mouseExited(MouseEvent arg0) {
                }

                @Override
                public void mouseEntered(MouseEvent g) {
                }

                @Override
                public void mouseClicked(MouseEvent g) {
                    try {
                        fcl.listen_mouse_click_game(g);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            this.setFocusable(true);

            this.addKeyListener(new KeyListener() {
                @Override
                public void keyTyped(KeyEvent e) {
                    //      System.out.println(System.currentTimeMillis()+"  keyTyped " + e.getKeyCode());
                }

                @Override
                public void keyReleased(KeyEvent e) {
                    Schedulers.single().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            //  System.out.println("thredId- "+Thread.currentThread().getId()+" "+Thread.currentThread().getName());
                            fcl.listen_key_release_game(e);
                        }
                    });
                }

                @Override
                public void keyPressed(KeyEvent e) {
                    Schedulers.single().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            //   System.out.println("thredId= "+Thread.currentThread().getId()+" "+Thread.currentThread().getName());
                            fcl.listen_key_press_game(e);
                        }
                    });
                }
            });

            if (gameSave.getTouZiProjects().size() == 0) {
                BoBuSchoolProject schoolProject = new BoBuSchoolProject();
                gameSave.getTouZiProjects().add(schoolProject);
                BaiShuDIProject baiShuDIProject = new BaiShuDIProject();
                gameSave.getTouZiProjects().add(baiShuDIProject);
                BoBuShaTanProject shaTanProject = new BoBuShaTanProject();
                gameSave.getTouZiProjects().add(shaTanProject);
            }
            if(!DEBUG_MODE){
                gameSave.getOtherEventMaps().put("home1*6*8", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*9", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*10", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*11", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*12", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*13", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*14", "hideplace");
                gameSave.getOtherEventMaps().put("home1*6*15", "hideplace");
                gameSave.getOtherEventMaps().put("home1*8*4", "hideplace");
            }
            //test
//            FCPlayerInfo p1 = new FCPlayerInfo();
//            p1.setSelectPlayer(0);
//            FCPlayerInfo p2 = new FCPlayerInfo();
//            p2.setSelectPlayer(1);
//            FCPlayerInfo p3 = new FCPlayerInfo();
//            p3.setSelectPlayer(2);
//            for (int i = 0; i < 100; i++) {
//                System.out.println("===========================");
//                p1.addExperience(1);
//                p2.addExperience(1);
//                p3.addExperience(1);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置边界
     */
    @Override
    public void setBounds(int x, int y, int width, int height) {
        super.setBounds(x, y, width, height);
        fcv.setNowWindowWidth(getWidth());
        fcv.setNowWindowHeight(getHeight());
        fcv.setMMTitleCoorY(getHeight());
        fcv.setProportion((getWidth() / 1920.0 > getHeight() / 1080.0) ? getHeight() / 1080.0 : getWidth() / 1920.0);
        FCUIConfig.getIn().resetProportion(fcv.getProportion());
//        System.out.println("获取得分辨：" + getWidth() + "*" + getHeight());
        font = new Font(FCRConstants.FONT_BLACK, 0, (int) (50 * fcv.getProportion()));
        fcv.setInfow((int) (634 * fcv.getProportion()));
        fcv.setInfoh((int) (46 * fcv.getProportion()));
        fcv.setPlayerw((int) (192 * fcv.getProportion()));
        fcv.setPlayerh((int) (44 * fcv.getProportion()));
        fon1 = new Font(FCRConstants.FONT_BLACK, 0, (int) (18 * fcv.getProportion()));
        playerbIp.setBounds((int) (871 * fcv.getProportion()), (int) (fcv.getProportion() * 525), (int) (fcv.getProportion() * 300),
                (int) (fcv.getProportion() * 30));
        playerbPort.setBounds((int) (fcv.getProportion() * 915), (int) (fcv.getProportion() * 585), (int) (fcv.getProportion() * 256),
                (int) (fcv.getProportion() * 30));
        playerbIp.setVisible(false);
        playerbPort.setVisible(false);
        playerbIp.setBackground(Color.black);
        playerbIp.setForeground(Color.white);
        playerbIp.setBorder(BorderFactory.createLineBorder(Color.black));
        playerbPort.setBackground(Color.black);
        playerbPort.setForeground(Color.white);
        playerbPort.setBorder(BorderFactory.createLineBorder(Color.black));
        if (messageText == null) {
            messageText = new JTextField();
            messageText.setBounds((int) (565 * fcv.getProportion()), (int) (880 * fcv.getProportion()), (int) (640 * fcv.getProportion()),
                    (int) (30 * fcv.getProportion()));
            messageText.setForeground(Color.white);
            messageText.setBorder(BorderFactory.createLineBorder(Color.black));
            messageText.setBackground(Color.black);
            messageText.setVisible(false);
            messageText.addKeyListener(new KeyListener() {
                @Override
                public void keyTyped(KeyEvent e) {
                }

                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == 10) {
                        FCRMaster.messageText.setVisible(false);
                        if (FCRMaster.fcv.isSever()) {
                            FCRSocketServer.getIn().sendBrocastPlayerMsg(FCRMaster.messageText.getText());
                        } else if (FCRMaster.fcv.isClient()) {
                            FCRSocketClient.getIn().sendBrocastPlayerMsg(FCRMaster.messageText.getText());
                        } else {
                            String msg = FCRMaster.messageText.getText();
                            if (msg == null) {
                                player1.setTalkingMsg(null);
                                return;
                            }
                            if (msg.length() == 0) {
                                player1.setTalkingMsg(null);
                                return;
                            }
                            if ("请输入对话".equals(msg)) {
                                player1.setTalkingMsg(null);
                                return;
                            }
                            if (msg.equals(player1.getTalkingMsg())) {
                                return;
                            }
                            if (msg.length() > 20) {
                                msg = msg.substring(0, 20);
                            }
                            player1.setTalkingMsg(msg);
                        }
                    }
                }

                @Override
                public void keyReleased(KeyEvent e) {

                }
            });
            playerName.setBounds((int) (940 * fcv.getProportion()), (int) (580 * fcv.getProportion()), (int) (230 * fcv.getProportion()),
                    (int) (40 * fcv.getProportion()));
            int fontSize = (int) (24 * fcv.getProportion());
            fontSize = fontSize < 9 ? 9 : fontSize;
            playerName.setFont(new Font(FCRConstants.FONT_BLACK, 0, fontSize));
            this.add(messageText);
            this.add(playerbIp);
            this.add(playerbPort);
        }
        fcv.setMapPngSize((int) (64 * fcv.getProportion()));
        fcv.setBattleY((int) (-1200 * fcv.getProportion()));
        if (fcMonsterBuildCoor == null) {
            fcMonsterBuildCoor = new FCMonsterBuildCoor();
        }
        defaultHomeScreen.dipatchSetBounds();
        singlePlayerReadyScreen.dipatchSetBounds();
        findRoomScreen.dipatchSetBounds();
        newRoomScreen.dipatchSetBounds();
        defaultMapScreen.dipatchSetBounds();
        defaultFightScreen.dipatchSetBounds();
        player1.setNeedCheckPerV(true);
        helpToolScreen.dipatchSetBounds();
    }// 设置边界方法结束


    /**
     * 画组件
     */
    @Override
    protected void paintComponent(Graphics g) {

        g.setColor(Color.black);
        g.fillRect(0, 0, getWidth(), getHeight());
        // 游戏界面
        if (fcv.getInterfacenum() == 5) {
            if (fcv.isBattle() && fcv.getBattleY() == 0) {// 战斗
                defaultFightScreen.paintComponent(g, this);
            } else {
                defaultMapScreen.paintComponent(g, this);
            }
        } else {
            IScreen screen = screenMaps.get(fcv.getInterfacenum());
            if (screen != null) {
                screen.paintComponent(g, this);
            }//界面都是按顺序的走，getInterfacenum 0， 1， ，2， 3， 4， 5
        }

        helpToolScreen.paintComponent(g, this);
    }// 画组件方法结束

    @Getter
    private double speed1 = 0;

    /**
     * 更新画面
     * frames计时器
     */
    private class updataUI extends TimerTask {
        @Override
        public void run() {
            if (fcv.getFrames() >= 520) {
                if (fcv.getMMTitleCoorY() > 0)
                    fcv.setMMTitleCoorY(fcv.getMMTitleCoorY() - getHeight() / 360);
                else
                    fcv.setMMTitleCoorY(0);
            }
            repaint();
            if (fcv.getFrames() < 1250) {
                fcv.setFrames(fcv.getFrames() + 1);
            }
            if (fcv.getInterfacenum() == 4)
                fcv.setLoadNum((fcv.getLoadNum() > 15) ? 0 : fcv.getLoadNum() + 1);
            if (fcv.getInterfacenum() == 5) {
                //TODO....
                if (fcv.getJumpactionnum() > -1) {
                    fcv.setJumpactionnum(fcv.getJumpactionnum() + 1);
                    if (fcv.getJumpactionnum() == 10 && fcv.getSaveUploadIsOk() == 1) {
                        FCEvent event = fcv.getPlayingEvent();
                        if (event != null && event.getType().equals("jump")) {
                            JumpEvent jumpEvent = (JumpEvent) event;
                            player1.setMapNameOfPlayer(jumpEvent.getDestination(), jumpEvent.getJumpx(), jumpEvent.getJumpy());
                            fcv.getNpcName().clear();
                            fcv.getNpcBundleHashMap().clear();
                            plotnpc1.clear();
                            HashMap<String, String> hashnpc = mapLib.getNPCOfName(player1.getMapname());
                            Set<String> hashset = hashnpc.keySet();
                            for (String opop : hashset) {
                                fcv.getNpcName().add(hashnpc.get(opop));
                                int dir = actionLib.getActionOfName(charLib.getCharacterOfName(hashnpc.get(opop)).getCharacterActionID())
                                        .getFace();
                                int my = Integer.parseInt(opop.split("\\*")[1]);
                                int mx = Integer.parseInt(opop.split("\\*")[0]);
                                FCAction act = actionLib.getActionOfName(charLib.getCharacterOfName(hashnpc.get(opop)).getCharacterActionID());
                                fcv.getNpcBundleHashMap().put(hashnpc.get(opop), new NpcBundle(hashnpc.get(opop), mx, my, dir, act.getType()));
                            }
                            player1.setPianYiY(0);
                            player1.setPianYiX(0);
                            //TODO SYNC
                            if (FCRMaster.fcv.isSever()) {
                                FCRSocketServer.getIn().playerMoving();
                            } else if (FCRMaster.fcv.isClient()) {
                                FCRSocketClient.getIn().playerMoving();
                            }
                        }
                    }
                    if (fcv.getJumpactionnum() > 20) {
                        fcv.setJumpactionnum(-1);
                        sound.setBackgroundMusic(((JumpEvent) fcv.getPlayingEvent()).getMusicnum1());
                    }
                }
                if (fcv.isMonsterBuilding() && !fcv.isBattle()) {
                    if (fcv.getBattleY() < -1199 * fcv.getProportion()) {// 生成怪物
                        fcv.setBattle(true);
                        sound.setBackgroundMusic(9);
                        fcv.getBattleMonster().clear();
                        fcv.getBattleWraps().clear();
                        fcv.getMutilPlayRandomV().clear();
                        Random floatR = new Random();
                        for (int i = 0; i < 70; i++) {
                            fcv.getMutilPlayRandomV().add(floatR.nextFloat());
                        }

                        String[] tmpmo = mapLib.getMapOfName(player1.getMapname())
                                .getMapMonsterIDOfCoor(player1.getPlayer1x(), player1.getPlayer1y()).split(",");
                        ArrayList<Integer> tmpRate = mapLib.getMapOfName(player1.getMapname())
                                .getTriggerRate(player1.getPlayer1x(), player1.getPlayer1y());
                        ArrayList<String> mo = new ArrayList<>();
                        ArrayList<Integer> triggerRate = new ArrayList<>();
                        for (int o = 0; o < tmpmo.length; o++) {
                            if(tmpmo[o].length() < 1){
                                continue;
                            }
                            FCMonster mm = monLib.getMonsterOfID(tmpmo[o]);
                            if (mm.getType2().equals("wanted") || mm.getType2().equals("boss")) {
                                if (!gameSave.getFcMonsterKillRecordMap().containsKey(tmpmo[o])) {
                                    mo.add(tmpmo[o]);
                                    triggerRate.add(tmpRate.get(o));
                                }
                            } else {
                                mo.add(tmpmo[o]);
                                triggerRate.add(tmpRate.get(o));
                            }
                        }

                        // 计算所有玩家等级之和,队伍里的
                        int allplayerlevel = player1.getLevel();
                        for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
                            FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
                            allplayerlevel += p.getLevel();
                        }
                        List<FCMonster> linshimonster = new ArrayList<>(0);
                        int monsternum = 0;
                        if (fcv.getBattleEvent() == null) {
                            int baseNum = FCMutilPlayCache.getTeamMembers().size();
                            baseNum = Math.max(1, baseNum);
                            baseNum = Math.min(3, baseNum); //一个人的时候2 ，2 个是4， 3个是6

                            //数量调整
                            Random ra = new Random();
                            monsternum = ra.nextInt(2 + allplayerlevel / 10) + baseNum;// 怪物数量

                            int[] mofanwei = new int[mo.size()];
                            int maxRand = 0;
                            // 怪物几率范围计算
                            for (int i = 0; i < mo.size(); i++) {
                                mofanwei[i] = triggerRate.get(i) + ((i > 0) ? mofanwei[i - 1] : 0);
                                // System.out.println("mofanwei[i]= "+mofanwei[i]+" "+triggerRate.get(i));
                            }
                            maxRand = mofanwei[mofanwei.length - 1];
                            // 生成怪物类型判断
                            for (int i = 0; i < monsternum; i++) {
                                int num = ra.nextInt(maxRand);
                                for (int j = 0; j < mofanwei.length; j++) {
                                    if (num < mofanwei[j]) {
                                        FCMonster m = monLib.getMonsterOfID(mo.get(j)).getClone();
                                        linshimonster.add(m);
                                        //TODO 同场必须出现伙伴数
                                        if (m.getPartnerFollow() != 0) {
                                            for (int po = 0; po < m.getPartnerFollow(); po++) {
                                                m = monLib.getMonsterOfID(mo.get(j)).getClone();
                                                linshimonster.add(m);
                                            }
                                        }
                                        if (m.getType2().equals("wanted") || m.getType2().equals("boss")) {
                                            //有一个就够了
                                            mofanwei[j] = 0;
                                        }
                                        break;
                                    }
                                }
                            }
                        } else {
                            //剧情战斗
                            for (String monId : ((BattleEvent) fcv.getBattleEvent()).getMonsterId()) {
                                linshimonster.add(monLib.getMonsterOfID(monId).getClone());
                            }
                            eventOrderHelper.dealBattleEvent((BattleEvent) fcv.getBattleEvent(), 1);
                        }

                        //TODO 怪物排序,应该按战力来排序，怪血量，速度，防御等计算,初步计算公式是  （对坦克攻击+防御+对人类主攻击*速度*0.8+血量）*(1+闪避几率)
//                        Comparator com2 = new Comparator<FCMonster>() {
//                            @Override
//                            public int compare(FCMonster o1, FCMonster o2) {
//                                int b1 = (int) ((o1.getGun1().getHurtToMan() + o1.getBlood() + o1.getDefense() + (o1.getGun1().getHurtToMan() * o1.getSpeed() * 0.8)) * (1 + (float) o1.getDodge() / 100));
//                                int b2 = (int) ((o2.getGun1().getHurtToMan() + o2.getBlood() + o2.getDefense() + (o2.getGun1().getHurtToMan() * o2.getSpeed() * 0.8)) * (1 + (float) o2.getDodge() / 100));
//                                return b2 - b1;
//                            }
//                        };
//                        Collections.sort(linshimonster, com2);

                        for (int i = 0; i < linshimonster.size(); i++) {
                            fcv.getBattleMonster().add(linshimonster.get(i));
                        }


                        // 怪物坐标以及尺寸计算
                        fcMonsterBuildCoor.buildMonsterCoor(fcv.getBattleMonster().size());
                        int currentPlayerNum = 1 + FCMutilPlayCache.getTeamMembers().size();
                        // 计算玩家坐标与尺寸
                        int firstplayerh = (int) (((1080 - 150 * currentPlayerNum) / 2) * fcv.getProportion());// 第一个玩家高度


                        FCPlayerBattleWrap wrap = new FCPlayerBattleWrap(player1.getAliasUID(), player1.getName(), fcv.getProportion(),
                                (int) ((1700 - 96) * fcv.getProportion()), firstplayerh, (int) (96 * fcv.getProportion()), (int) (102 * fcv.getProportion()));
                        wrap.setBattleDriverTank(!player1.getPlayertank1().equals("null"));
                        if (player1.getLongTermMap().size() > 0) {
                            Iterator<Map.Entry<String, FCLongTermState>> iterator = player1.getLongTermMap().entrySet().iterator();
                            while (iterator.hasNext()) {
                                Map.Entry<String, FCLongTermState> entry = iterator.next();
                                wrap.addlongTermState(entry.getKey(), entry.getValue().value, entry.getValue().rounds);
                            }
                        }
                        fcv.getBattleWraps().add(wrap);

                        for (int i = 0; i < FCMutilPlayCache.getTeamMembers().size(); i++) {
                            FCRPlayerLink link = FCMutilPlayCache.getTeamMembers().get(i);
                            FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
                            FCPlayerBattleWrap wrap2 = new FCPlayerBattleWrap(p.getAliasUID(), p.getName(), fcv.getProportion(),
                                    (int) ((1700 - 96) * fcv.getProportion()),
                                    (int) ((fcv.getProportion() * 150) * (i + 1) + firstplayerh), (int) (96 * fcv.getProportion()), (int) (102 * fcv.getProportion()));
                            wrap2.setBattleDriverTank(!p.getPlayertank1().equals("null"));

                            Iterator<Map.Entry<String, FCLongTermState>> iterator = p.getLongTermMap().entrySet().iterator();
                            while (iterator.hasNext()) {
                                Map.Entry<String, FCLongTermState> entry = iterator.next();
                                wrap2.addlongTermState(entry.getKey(), entry.getValue().value, entry.getValue().rounds);
                            }
                            fcv.getBattleWraps().add(wrap2);
                            FCTank a = tankLib.getTankOfID(p.getPlayertank1(), p.getPlayertankHostId());
                            if (a != null) {
                                a.reInitShuxing();
                            }
                        }


                        if (fcv.isSever()) {
                            FCRSocketServer.getIn().syncJumpToBattle();
                        } else if (fcv.isClient()) {
                            FCRSocketClient.getIn().syncJumpToBattle();
                        }

                        fcv.setFightMenuBntSelect(-1);
                        fcv.setBattleReady(true);
                        fcv.setBattleAnimationNum(0);
                        fcv.setMonsterBuilding(false);
                        defaultFightScreen.selectNextPlayer();
                    }
                }
                try {
                    if (fcv.isBattle() && fcv.getBattleY() <= 0 && !fcv.isBattleEnd()) {
                        fcv.setBattleY(fcv.getBattleY() + (int) (80 * fcv.getProportion()));
                        fcv.setBattleY((-fcv.getBattleY() < 20 * fcv.getProportion()) ? 0 : fcv.getBattleY());
                    }
                    if (fcv.isBattleEnd() && fcv.getBattleY() > -1200 * fcv.getProportion()) {
                        fcv.setBattleY(fcv.getBattleY() - (int) (80 * fcv.getProportion()));
                    }
                    if (fcv.getBattleY() <= -1200 * fcv.getProportion()) {
                        if (fcv.isBattle())
                            sound.setBackgroundMusic(fcv.getOldMusicNum());
                        fcv.setBattleEnd(false);
                        fcv.setBattle(false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (fcv.getShopVendingSelectNum() > 0) {// 进行摇奖-售货机
                    ShopEvent shopEvent = (ShopEvent) fcv.getPlayingEvent();
                    if (player1.getMoney() >= shopEvent.getItemprice().get(fcv.getShopVendingSelectNum() - 1)) {
                        if (player1.getKnapsackItemNum() < 10) {
                            fcv.setShopLuckDrawJ(fcv.getShopLuckDrawJ() + 2);
                            fcv.setShopVendingTip(FCRConstants.SVT_DO_LOTTERY);
                            if (fcv.getShopLuckDrawJ() > fcv.getShopLuckDrawI()) {
                                if (fcv.getShopLuckDrawI() < 1 && fcv.isShopLuckDraw())
                                    fcv.setShopLuckDraw(false);
                                if (fcv.getShopLuckDrawI() <= 0 && fcv.getShopLuckDrawN() > 0) {
                                    fcv.setShopLuckDrawN(fcv.getShopLuckDrawN() - 1);
                                } else {
                                    if (fcv.isShopLuckDraw())
                                        fcv.setShopLuckDrawI(fcv.getShopLuckDrawI() - 4);
                                    else
                                        fcv.setShopLuckDrawI(fcv.getShopLuckDrawI() + 4);
                                }
                                fcv.setShopLuckDrawJ(0);
                                fcv.setShopLampNum(fcv.getShopLampNum() + 1);
                                if (fcv.getShopLampNum() > fcv.getShopLampCoor().length - 1)
                                    fcv.setShopLampNum(0);
                            }
                            if (fcv.getShopLuckDrawI() > 50) {
                                FCItem buyItem = itemLib.getItemOfID(shopEvent.getItemid().get(fcv.getShopVendingSelectNum() - 1));
                                player1.addMoney(-buyItem.getBuyInPrice());
                                //TODO 坦克道具一定要放坦克背包
                                if (buyItem.getCatalog().equals("tank")) {
                                    FCTank tank = FCItemForTankHelper.findTankHasBag();
                                    if (tank != null) {
                                        tank.addItemToKnapsack(buyItem.getName());
                                    } else {
                                        fcv.setShopVendingTip(FCRConstants.SVT_NO_TANK);
                                    }
                                } else {
                                    player1.addItemToKnapsack(buyItem.getName());
                                }
                                if (fcv.getShopLampNum() == 0 || fcv.getShopLampNum() == 8) {
                                    sound.setEffectSound(22);
                                    //获得奖品
                                    FCItem rewardItem = itemLib.getItemOfID(shopEvent.getRewarditemid());
                                    if (rewardItem.getCatalog().equals("tank")) {
                                        FCTank tank = FCItemForTankHelper.findTankHasBag();
                                        if (tank != null) {
                                            tank.addItemToKnapsack(rewardItem.getName());
                                        } else {
                                            fcv.setShopVendingTip(FCRConstants.SVT_WIN_BUT_BACKPACK_FULL);
                                        }
                                    } else {
                                        if (player1.addItemToKnapsack(shopEvent.getRewarditemid())) {
                                            fcv.setShopVendingTip(FCRConstants.SVT_WIN_THE_PRIZE);
                                        } else {
                                            fcv.setShopVendingTip(FCRConstants.SVT_WIN_BUT_BACKPACK_FULL);
                                        }
                                    }
                                } else {
                                    fcv.setShopVendingTip(FCRConstants.SVT_MISS_THE_PRIZE);
                                }
                                fcv.setShopLuckDrawJ(0);
                                fcv.setShopLuckDrawI(30);
                                fcv.setShopVendingSelectNum(0);
                                fcv.setShopLuckDraw(true);
                                fcv.setShopLuckDrawN(120);
                            }
                        } else {
                            fcv.setShopVendingTip(FCRConstants.SVT_BACKPACK_FULL);
                            fcv.setShopLuckDrawJ(0);
                            fcv.setShopLuckDrawI(30);
                            fcv.setShopVendingSelectNum(0);
                            fcv.setShopLuckDraw(true);
                            fcv.setShopLuckDrawN(120);
                        }
                    } else {
                        fcv.setShopVendingTip(FCRConstants.SVT_NO_COINS_TO_BUY);
                        fcv.setShopLuckDrawJ(0);
                        fcv.setShopLuckDrawI(30);
                        fcv.setShopVendingSelectNum(0);
                        fcv.setShopLuckDraw(true);
                        fcv.setShopLuckDrawN(120);
                    }
                }
            }
        }
    }

    private class MoveAction extends TimerTask {

        @Override
        public void run() {
            if (fcv.getInterfacenum() == 5) {
                if (!fcv.isMonsterBuilding() && fcv.getJumpactionnum() < 0) {
                    if (fcv.isSliding()) {
                        if (Math.abs(player1.getPianYiX()) != 0 || Math.abs(player1.getPianYiY()) != 0
                                || player1.getPlayer1x() != fcv.getSlideTargetMapX() || player1.getPlayer1y() != fcv.getSlideTargetMapY()) {
                            playerSlideAction();
                        } else {
                            if (playerSlideCallback != null) {
                                playerSlideCallback.onSlideToTarget(true);
                            }
                            fcv.setSliding(false);
                            FCRMaster.gameSave.perV = 12;
                            FCMap map = mapLib.getMapOfName(player1.getMapname());
                            map.removeAlldynamicMapAnimation();
                        }
                    } else {
                        if (Math.abs(player1.getPianYiX()) != 0 || Math.abs(player1.getPianYiY()) != 0) {
                            playeraction();
                        } else if ((fcv.isDirDown() || fcv.isDirUp() || fcv.isDirLeft() || fcv.isDirRight())) {
                            if (fcv.isDirDown()) {
                                FCRMaster.player1.setActionDir(0);
                            } else if (fcv.isDirUp()) {
                                FCRMaster.player1.setActionDir(3);
                            } else if (fcv.isDirLeft()) {
                                FCRMaster.player1.setActionDir(1);
                            } else if (fcv.isDirRight()) {
                                FCRMaster.player1.setActionDir(2);
                            }
                            playeraction();
                        } else {
                            if (player1.getActionNum() != 0) {
                                player1.setActionNum(0);
                                player1.disPatchActionNum(FCMutilPlayCache.teamLink, 0);
                            }
                        }
                    }
                }
            }
        }
    }

    private void playerSlideAction() {
        if (fcv.isPlotJumpStep1()) {
            //TODO 剧情中不给动了
            return;
        }
        int playerX = player1.getPlayer1x();
        int playerY = player1.getPlayer1y();
        if (playerAction.slideAction(fcv.getSlideDir())) {
            //SYNC
            if (FCRMaster.fcv.isSever()) {
                FCRSocketServer.getIn().playerMoving();
            } else if (FCRMaster.fcv.isClient()) {
                FCRSocketClient.getIn().playerMoving();
            }
            if (player1.getActionNum() != 0) {
                player1.setActionNum(0);
                player1.disPatchActionNum(FCMutilPlayCache.teamLink, 0);
            }
            if (!fcv.isInTeamLink() && (playerX != player1.getPlayer1x() || playerY != player1.getPlayer1y())) {
                flowmoving(true);
            }
        } else {
            //TODO 前方不能滑动了,要结束滑动
            fcv.setSliding(false);
            if (playerSlideCallback != null) {
                playerSlideCallback.onSlideToTarget(false);
            }
            FCRMaster.gameSave.perV = 12;
            FCMap map = mapLib.getMapOfName(player1.getMapname());
            map.removeAlldynamicMapAnimation();
        }
    }

    //跟随移动了格子
    public void flowmoving(boolean changeMapStopSlide) {

        //TODO 要遍历队伍，门开的
        FCPlayerInfo checkPlayer = player1;
        boolean isDoorOpening = false;
        int cx = -1, cy = -1;
        for (int i = -1; i < FCMutilPlayCache.getTeamMembers().size(); i++) {
            if (i != -1) {
                FCRPlayerLink fcrPlayerLink = FCMutilPlayCache.getTeamMembers().get(i);
                checkPlayer = FCMutilPlayCache.findPlayerByName(fcrPlayerLink.curPlayerHostUID, fcrPlayerLink.curPlayerName);
            }

            cx = checkPlayer.getPlayer1CoorX();
            cy = checkPlayer.getPlayer1CoorY();

            String blockname = mapLib.getMapOfName(player1.getMapname())
                    .getPlaceNameOfCoor(cx, cy);
            if (!blockname.startsWith("Men")) {
                cx = checkPlayer.getPlayer1CoorX() + 1;
                blockname = mapLib.getMapOfName(player1.getMapname())
                        .getPlaceNameOfCoor(cx, cy);
            }

            if (blockname.startsWith("Men")) {
                //TODO 是门,判断有没有门事件，要是没有就直接开门，
                FCEvent mayBeDoor = eventLib.getEventOfName(mapLib.getMapOfName(player1.getMapname())
                        .getEventNameOfCoor(cx, cy));
                if (mayBeDoor == null) {
                    isDoorOpening = true;
                } else if (mayBeDoor instanceof DoorEvent) {
                    //是门，判断有没有钥匙吧,或者已经开过了，
                    if (gameSave.getSaveAllHasUnLockDoors().contains(mayBeDoor.getName())) {
                        isDoorOpening = true;
                    }
                }
            }
            if (isDoorOpening) {
                break;//碰到要开们的就跳出了
            }
        }

        if (isDoorOpening) {
            if (!isplayopendoormusic) {
                opendoorx = cx;
                opendoory = cy;
                isplayopendoormusic = true;
                sound.setEffectSound(16);
                if (FCRMaster.fcv.isSever()) {
                    FCRSocketServer.getIn().syncMultiPlayScreen();
                } else if (FCRMaster.fcv.isClient()) {
                    FCRSocketClient.getIn().syncMultiPlayScreen();
                }
            }
        } else {
            if (isplayopendoormusic) {
                isplayopendoormusic = false;
                sound.setEffectSound(16);
                if (FCRMaster.fcv.isSever()) {
                    FCRSocketServer.getIn().syncMultiPlayScreen();
                } else if (FCRMaster.fcv.isClient()) {
                    FCRSocketClient.getIn().syncMultiPlayScreen();
                }
            }
        }


        fcv.setPlayingEvent(eventLib.getEventOfName(mapLib.getMapOfName(player1.getMapname())
                .getEventNameOfCoor(player1.getPlayer1CoorX(), player1.getPlayer1CoorY())));
        if (fcv.getPlayingEvent() != null) {
            if (fcv.getPlayingEvent().getType().equals("jump")) {
                if (!gameSave.getOtherEventMaps().containsKey(player1.getMapname() + "*" + player1.getPlayer1CoorX() + "*" + player1.getPlayer1CoorY())) {
                    //TODO 该事件还没被隐藏，针对拉多帐篷的显示和隐藏
                    sound.setEffectSound(((JumpEvent) fcv.getPlayingEvent()).getMusicnum0());
                    if (changeMapStopSlide) {
                        if (playerSlideCallback != null) {
                            playerSlideCallback.onSlideToTarget(false);
                        }
                        fcv.setSliding(false);
                        FCRMaster.gameSave.perV = 12;
                        FCMap map = mapLib.getMapOfName(player1.getMapname());
                        map.removeAlldynamicMapAnimation();
                    }
                    fcv.setJumpactionnum(0);
                    //TODO 通知队友也要转场了
                    if (FCRMaster.fcv.isSever()) {
                        FCRSocketServer.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), ((JumpEvent) fcv.getPlayingEvent()).getDestination());
                    } else if (FCRMaster.fcv.isClient()) {
                        FCRSocketClient.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), ((JumpEvent) fcv.getPlayingEvent()).getDestination());
                    }
                }
            } else if (fcv.getPlayingEvent().getType().equals("stepOn")) {
                autoTriggerEventHelper.dealAutoTriggerFcEvents(fcv.getPlayingEvent());
            }
//                    else if (fcv.getPlayingEvent().getType().equals("battle")) {
//                        if (!gameSave.getBattleEventEndIds().contains(fcv.getPlayingEvent().getName())) {
//                            //TODO 剧情没过，打吧
//                            fcv.setBattleEvent(fcv.getPlayingEvent());
//                            fcv.setBattleRounds(1);
//                            fcv.setMonsterBuilding(true);
//                            fcv.setOldMusicNum(sound.getNowMusicNum());
//                            sound.setBackgroundMusic(8);
//                        }
//                    }
        }

        movingSetTank();
        if (fcv.isSever()) {
            FCRSocketServer.getIn().syncYouTankMoving();
        } else if (fcv.isClient()) {
            FCRSocketClient.getIn().syncYouTankMoving();
        }
    }

    /**
     * 玩家行为
     */
    private void playeraction() {
        if (fcv.isPlotJumpStep1()) {
            //TODO 剧情中不给动了
            return;
        }
        speed1++;
        if (speed1 > 5) {//为了更改行走图的
            player1.setActionNum(player1.getActionNum() + 1);
            player1.disPatchActionNum(FCMutilPlayCache.teamLink, player1.getActionNum());
            speed1 = 0;
        }

        if (!fcv.isMonsterBuilding()) {
            int playerX = player1.getPlayer1x();
            int playerY = player1.getPlayer1y();
            if (!fcv.isBattle() && playerAction.playerAction()) {
                //SYNC
                if (FCRMaster.fcv.isSever()) {
                    FCRSocketServer.getIn().playerMoving();
                } else if (FCRMaster.fcv.isClient()) {
                    FCRSocketClient.getIn().playerMoving();
                }
                //TODO 不在别人的队伍里
                if (!fcv.isInTeamLink() && (playerX != player1.getPlayer1x() || playerY != player1.getPlayer1y())) {//走一格才判断一次,
                    if (fcv.getYuGuaiStepLimit() < 0) {
                        if (!fcv.isMonsterBuilding() && fcv.isOpenENMonster() && mapLib.getMapOfName(player1.getMapname())
                                .getMapMonsterIDOfCoor(player1.getPlayer1CoorX(), player1.getPlayer1CoorY()).length() > 1) {
                            int dRand = new Random(System.currentTimeMillis()).nextInt(100);
                            int yuGuaiJiLvValAdd = 0;

                            //TODO 判断是否有开了迷彩条，减少遇怪几率
                            FCTank fcTank = tankLib.getTankOfID(player1.getPlayertank1(), player1.getPlayertankHostId());
                            if (fcTank != null && fcTank.isOpenMiCaiTiao()) {
                                yuGuaiJiLvValAdd = 8;
                            } else {
                                for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
                                    FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
                                    fcTank = tankLib.getTankOfID(p.getPlayertank1(), p.getPlayertankHostId());
                                    if (fcTank != null && fcTank.isOpenMiCaiTiao()) {
                                        yuGuaiJiLvValAdd = 8;
                                        break;
                                    }
                                }
                            }
                            //判断是否有开了迷彩条，减少遇怪几率
                            if (dRand > (gameSave.getYuGuaiJilv() + yuGuaiJiLvValAdd)) {
                                fcv.setMonsterBuilding(true);
                                fcv.setOldMusicNum(sound.getNowMusicNum());
                                sound.setBackgroundMusic(8);
                                fcv.setYuGuaiStepLimit(0);
                            }
                            fcv.setOpenENMonster(false);
                        }
                    } else {
                        fcv.setYuGuaiStepLimit(fcv.getYuGuaiStepLimit() + 1);
                        if (fcv.getYuGuaiStepLimit() > 2) {
                            fcv.setYuGuaiStepLimit(-1);
                        }
                    }
                    flowmoving(false);
                }
            }
        }
    }// 玩家行为方法结束

    //TODO 坦克移动
    public void movingSetTank() {
        FCPlayerInfo checkPlayer = player1;
        for (int i = -1; i < FCMutilPlayCache.getTeamMembers().size(); i++) {
            if (i == -1) {
            } else {
                FCRPlayerLink link = FCMutilPlayCache.getTeamMembers().get(i);
                checkPlayer = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
            }
            if (checkPlayer != null && checkPlayer.getAliasUID().equals(gameSave.HOST_UID)) {
                FCTank fcTank = tankLib.getTankOfID(checkPlayer.getPlayertank1(), checkPlayer.getPlayertankHostId());
                if (fcTank != null) {
                    fcTank.setPmapname(player1.getMapname());
                    fcTank.setPcoorX(checkPlayer.getPlayer1x());
                    fcTank.setPcoorY(checkPlayer.getPlayer1y());
                    fcTank.setPPianYiX(0);
                    fcTank.setPPianYiY(0);
                    fcTank.setPdir(checkPlayer.getActionDir());
                    fcTank.setPactionNum(checkPlayer.getActionNum());
                }
            }
        }
    }


    private int npcactivenum = 0;
// npc行为线程

    private class updataNPCActive extends TimerTask {
        private ClickHelper timeLimit = new ClickHelper(500);//每n毫秒npc动作切换一次
        Random random = new Random();
        private ClickHelper touZiCheck = new ClickHelper(60000);//
        private ClickHelper autoSave = new ClickHelper(20000);//

        public updataNPCActive() {
            autoSave.setClickLock(true);
            touZiCheck.setDelayProcess();
        }

        @Override
        public void run() {
            try {
                if (touZiCheck.canClick()) {
                    for (FCTouZiProject project : gameSave.getTouZiProjects()) {
                        project.getHuiBaoMoney();//检查收益
                    }
                }
                if (autoSave.canClick()) {
                    Schedulers.io().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            if (FCDataSingles.getWriter().writeSaveData(FCRMaster.player1, FCRMaster.gameSave, FCRMaster.gamedate, FCRMaster.tankLib)) {
                                FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_SUCCESS);
                            } else {
                                FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_FAILURE);
                            }
                        }
                    });
                    autoSave.setClickLock(true);
                    fcv.setSetAutoSave(false);
                }
                if (fcv.isSetAutoSave()) {
                    autoSave.setClickLock(false);
                    autoSave.setDelayProcess();
                    fcv.setSetAutoSave(false);
                }
                FCRMaster.fcv.showMessage();
                if (timeLimit.canClick()) {
                    npcactivenum = (++npcactivenum > 3) ? 0 : npcactivenum;
                } // npc动作切换编号
                // 计算npc动作
                for (int i = 0; i < fcv.getNpcName().size(); i++) {
                    // 未进剧情的npc动作
                    if (!plotnpc1.contains(fcv.getNpcName().get(i)) && !plotnpc2.contains(fcv.getNpcName().get(i))) {
                        String npcName = fcv.getNpcName().get(i);
                        NpcBundle npcBundle = fcv.getNpcBundleHashMap().get(npcName);
                        if (npcBundle == null) {
                            return;
                        }
                        if (!fcv.getNpcName().get(i).equals(fcv.getSayNpcName())) {
                            int x1 = npcBundle.locationX;
                            int y1 = npcBundle.locationY;
                            int x2 = npcBundle.targetX;
                            int y2 = npcBundle.targetY;
                            int[] mapsize = mapLib.getMapOfName(player1.getMapname()).getMapSize();// 获取地图尺寸

                            String key = charLib.getCharacterOfName(npcName).getCharacterActionID() + "," + npcName;
                            FCAction act = actionLib.getActionOfNpcInfo(key);
                            int npcdir = act.getFace();// 获取npc朝向
                            String jgh = act.getType();// 获取npc行为类型
                            if (npcBundle.stopTimes > 0) {
                                npcBundle.stopTimes--;
                            }
                            if (npcBundle.stopTimes > 0) {
                                //停顿操作,不做任何行动了,方便玩家去和npc对话
                                npcBundle.actionNum = 0;
                                continue;
                            }
                            if (jgh.equals("random") || jgh.equals("fixed")) {
                                if (jgh.equals("random")) {//要是是路线，严格按照路线的方向就行了
                                    if (npcBundle.offSetX == 0 && npcBundle.offSetY == 0) {
                                        //等于0了才能换方向
                                        if (x1 != x2) {
                                            if (x2 - x1 < 0)
                                                npcdir = 3;
                                            if (x2 - x1 > 0)
                                                npcdir = 0;
                                        }
                                        int a = random.nextInt(10);
                                        if (a > 4) {
                                            if (y1 != y2) {
                                                if (y2 - y1 > 0)
                                                    npcdir = 2;
                                                if (y2 - y1 < 0)
                                                    npcdir = 1;
                                            }
                                        }
                                    }
                                }
                                act.setFace(npcdir);
                                boolean isend = false;// 前方是否可以通行或到达目的地
                                if (npcBundle.offSetX == 0 && npcBundle.offSetY == 0) {
                                    if (x1 == x2 && y1 == y2) {
                                        isend = true;// 到达目的地
                                    } else if (npcdir == 0) {//向下走
                                        if (x1 + 1 >= mapsize[1]) {
                                            isend = true;
                                        } else if (checkIsPengzhuangOthers(x1 + 1, y1))//如果下一个xy就是player1了那就不走了结束
                                        {
                                            npcBundle.stopTimes = 20;
                                            isend = true;
                                        } else if (mapLib.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x1 + 1, y1) >= 1) {
                                            isend = true;// 往下前方障碍,地图物的障碍
                                        }
                                    } else if (npcdir == 3) {
                                        if (x1 - 1 <= 0) {
                                            isend = true;
                                        } else if (checkIsPengzhuangOthers(x1 - 1, y1)) {
                                            npcBundle.stopTimes = 20;
                                            isend = true;
                                        } else if (mapLib.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x1 - 1, y1) >= 1) {
                                            isend = true;// 往上前方障碍
                                        }
                                    } else if (npcdir == 1) {
                                        if (y1 - 1 <= 0) {
                                            isend = true;// 往左前方边界
                                        } else if (checkIsPengzhuangOthers(x1, y1 - 1)) {
                                            npcBundle.stopTimes = 20;
                                            isend = true;
                                        } else if (mapLib.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x1, y1 - 1) >= 1) {
                                            isend = true;// 往左前方障碍
                                        }
                                    } else if (npcdir == 2) {
                                        if (y1 + 1 >= mapsize[0]) {
                                            isend = true;// 往右前方障碍
                                        } else if (checkIsPengzhuangOthers(x1, y1 + 1)) {
                                            npcBundle.stopTimes = 20;
                                            isend = true;
                                        } else if (mapLib.getMapOfName(player1.getMapname()).getMapEntityOfCoor(x1, y1 + 1) >= 1) {
                                            isend = true;// 往右前方障碍
                                        }
                                    }
                                }
                                if (!isend) {
                                    npcmove(npcBundle, npcdir, x1, y1);
                                } else {
                                    int fixdir = setNpcNewTarget(npcBundle, npcdir, act, mapsize);
                                    if (jgh.equals("fixed")) {
                                        act.setFace(fixdir);
                                    }
                                    //  System.out.println("newTarget "+npcBundle.targetX+"*"+npcBundle.targetY);
                                }
                            } else {
                                if (jgh.equals("step")) {
                                    npcBundle.npcDir = npcdir;
                                    npcBundle.actionNum = npcactivenum;
                                } else if (jgh.equals(FCAction.TYPE_RANDOM_DIR)) {
                                    npcBundle.npcDir = act.getRandomDir(npcBundle.npcDir);
                                } else {
                                    npcBundle.npcDir = act.getFace();
                                }
                            }
                        } else {
                            int x1 = npcBundle.locationX;
                            int y1 = npcBundle.locationY;
                            int npcdir = 0;
                            if (x1 != player1.getPlayer1CoorX()) {
                                if (player1.getPlayer1CoorX() - x1 < 0)
                                    npcdir = 3;
                                if (player1.getPlayer1CoorX() - x1 > 0)
                                    npcdir = 0;
                            }
                            if (y1 != player1.getPlayer1CoorY()) {
                                if (player1.getPlayer1CoorY() - y1 > 0)
                                    npcdir = 2;
                                if (player1.getPlayer1CoorY() - y1 < 0)
                                    npcdir = 1;
                            }
                            npcBundle.npcDir = npcdir;
                            npcBundle.actionNum = 0;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private boolean checkIsPengzhuangOthers(int willX, int willY) {
            //碰到角色呢
            if (player1.getPlayer1CoorX() == willX && player1.getPlayer1CoorY() == willY) {
                return true;
            }
            //碰到队友呢
            for (FCRPlayerLink link : FCMutilPlayCache.getTeamMembers()) {
                FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(link.curPlayerHostUID, link.curPlayerName);
                if (p != null && p.getPlayer1x() == willX && p.getPlayer1y() == willY) {
                    return true;
                }
            }
            //检测是否碰坦克
            CopyOnWriteArrayList<FCPropulsion> fcPropulsions = FCMutilPlayPropulsionCache.mapToPropulsionMap.get(player1.getMapname());
            if (fcPropulsions != null) {
                for (FCPropulsion propulsion : fcPropulsions) {
                    if (propulsion.getVisable() == 1 && propulsion.getPcoorX() == willX && propulsion.getPcoorY() == willY) {
                        return true;
                    }
                }
            }
            //碰到其他npc也不行
            boolean isExistNPC = FCRMaster.fcv.checkAndGetNpcInXYTag(willX + "*" + willY) != null;
            String key = player1.getMapname() + "*" + willX + "*" + willY;
            if (isExistNPC) {
                if (gameSave.getBattleBossMaps().containsKey(key) || gameSave.getOtherEventMaps().containsKey(key)) {
                    //TODO 哪就是这个npc是个boss，已经被打掉了,不会在显示了
                    isExistNPC = false;
                }
            }
            return isExistNPC;
        }

        private void npcmove(NpcBundle bundle, int dir, int x1, int y1) {
            bundle.npcDir = dir;
            bundle.actionNum = npcactivenum;
            int pianyix = 0;
            int pianyiy = 0;
            int vSpeedLevel = 16;
            int vPerStep = (int) (64 * fcv.getProportion() / vSpeedLevel);//表示一步走vPerStep个像素
            if (dir == 0) {
                pianyiy = bundle.offSetY + vPerStep;
                if (pianyiy >= 64 * FCRMaster.fcv.getProportion()) {
                    bundle.locationX = x1 + 1;
                    pianyiy = 0;
                }
                bundle.offSetY = pianyiy;
            } else if (dir == 3) {
                pianyiy = bundle.offSetY - vPerStep;
                if (pianyiy <= -(int) (64 * FCRMaster.fcv.getProportion())) {
                    bundle.locationX = x1 - 1;
                    pianyiy = 0;
                }
                bundle.offSetY = pianyiy;
            } else if (dir == 1) {
                pianyix = bundle.offSetX - vPerStep;
                if (pianyix < -(int) (64 * FCRMaster.fcv.getProportion())) {
                    bundle.locationY = y1 - 1;
                    pianyix = 0;
                }
                bundle.offSetX = pianyix;
            } else if (dir == 2) {
                pianyix = bundle.offSetX + vPerStep;
                if (pianyix > (int) (64 * FCRMaster.fcv.getProportion())) {
                    bundle.locationY = y1 + 1;
                    pianyix = 0;
                }
                bundle.offSetX = pianyix;
            }
            // System.out.println("move " + bundle.locationX + "*" + bundle.locationY + " offSet:" + bundle.offSetX + "*" + bundle.offSetY + " npcdir:" + dir);

        }

        /**
         * 设置npc的新目标
         *
         * @param dir
         * @param act
         * @param mapsize
         */
        private int setNpcNewTarget(NpcBundle bundle, int dir, FCAction act, int[] mapsize) {
            int[] npcAction = act.getNPCAction(dir, bundle.routeId, bundle.targetX == bundle.locationX && bundle.targetY == bundle.locationY);
            bundle.routeId = npcAction[0];// 设置路线编号
            if (npcAction[1] == 0) {// 设置向下目标
                if (bundle.targetX + npcAction[2] >= mapsize[1]) {
                    bundle.targetX = mapsize[1] - 1;
                } else {
                    bundle.targetX += npcAction[2];
                }
            } else if (npcAction[1] == 3) {// 设置向上目标
                if (bundle.targetX - npcAction[2] < 0) {
                    bundle.targetX = 0;
                } else {
                    bundle.targetX -= npcAction[2];
                }
            } else if (npcAction[1] == 1) {// 设置向左目标
                if (bundle.targetY - npcAction[2] < 0) {
                    bundle.targetY = 0;
                } else {
                    bundle.targetY -= npcAction[2];
                }
            } else if (npcAction[1] == 2) {// 设置向右目标
                if (bundle.targetY + npcAction[2] >= mapsize[0]) {
                    bundle.targetY = mapsize[0] - 1;
                } else {
                    bundle.targetY += npcAction[2];
                }
            }
            return npcAction[1];
        }
    }

    /**
     * 攻击动画计算线程
     */
    private class battleAnimationData extends TimerTask {

        @Override
        public void run() {
            //TODO 回合判断 isBattleHurtCount false就是到了玩家ready， true就是执行了
            if (fcv.isMonsterBuilding()) {
                return;
            }
            if (fcv.isBattleHurtCount()) {
                if (fcv.getBattleAttackOrder().size() > 0) {
                    // 计算我方攻击,在第60帧时
                    FCBattleOrder order = fcv.getBattleAttackOrder().peek();
                    //order执行结束了
                    if (fcv.getBattleAnimationNum() > order.frameTimes) {
                        FCBattleOrder newOrder = null;//产生的新指令
                        //TODO 主要是解析指令
                        if (order.battleType == 1) {//是角色操作
                            newOrder = playerBattleOrderHelper.dealPlayerBattleOrderEnd(order);
                            //TODO 每一个角色回合结束都调用一次
                            FCPlayerBattleWrap nowWrap = FCPlayerBattleWrap.findBattleWrapByName(order.playerUid, order.playerName);
                            nowWrap.endOfRound();
                        } else if (order.battleType == 2) {//怪物的回合
                            newOrder = monsterBattleOrderHelper.dealMonsterBattleOrderEnd(order);
                            //TODO 必须查找倒怪物指令里已经没有这个怪的指令了才算回合结束
                            int findAllThisMsOrders = 0;
                            for (FCBattleOrder b : fcv.getBattleAttackOrder()) {
                                if (b.battleType == 2 && b.monsterNum == order.monsterNum) {
                                    findAllThisMsOrders++;
                                }
                            }
                            if (findAllThisMsOrders <= 1) {
                                FCMonster monster = fcv.getBattleMonster().get(order.monsterNum);
                                monster.endOfRound();
                            }
                        }

                        if (fcv.getBattleAttackOrder().size() > 0) {
                            fcv.getBattleAttackOrder().pop();
                        }
                        if (newOrder != null) {
                            fcv.getBattleAttackOrder().addFirst(newOrder);
                        }
                        fcv.showMessage();
                        fcv.setBattleAnimationNum(-1);
                    } else {
                        FCBattleOrder newOrder = null;//产生的新指令就是目标死了，更换目标
                        //TODO 那就是这个指令需要渲染动画
                        if (order.battleType == 1) {//是角色操作
                            newOrder = playerBattleOrderHelper.dealPlayerBattleOrder(order, fcv.getBattleAnimationNum());
                        } else if (order.battleType == 2) {//怪物的回合
                            newOrder = monsterBattleOrderHelper.dealMonsterBattleOrder(order, fcv.getBattleAnimationNum());
                        }
                        if (newOrder != null) {
                            fcv.getBattleAttackOrder().addFirst(newOrder);
                        }
                    }
                }

                fcv.setBattleAnimationNum(fcv.getBattleAnimationNum() + 1);

                //TODO 判断队伍是否全灭了
                boolean allDie = true;
                for (FCPlayerBattleWrap per : fcv.getBattleWraps()) {
                    FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(per.getHostUid(), per.getName());
                    if (p != null && p.getBlood() > 0) {
                        allDie = false;
                        break;
                    }
                }
                //TODO 计算该回合是否结束
                if (!allDie && fcv.getBattleAttackOrder().size() == 0) {

                    //还不可以结算
                    if (!fcv.isInTeamLink()) {
                        int needRands = 70 - fcv.getMutilPlayRandomV().size();
                        Random floatR = new Random();
                        ArrayList<Float> syncRandoms = new ArrayList<>(needRands);
                        for (int i = 0; i < needRands; i++) {
                            float f = floatR.nextFloat();
                            syncRandoms.add(f);
                        }
                        System.out.println("现在随机数 " + fcv.getMutilPlayRandomV().size() + " 增加随机数 " + syncRandoms.size());
                        fcv.getMutilPlayRandomV().addAll(syncRandoms);
                        if (FCRMaster.fcv.isSever()) {
                            FCRSocketServer.getIn().syncBattleRandoms(syncRandoms);
                        } else if (FCRMaster.fcv.isClient()) {
                            FCRSocketClient.getIn().syncBattleRandoms(syncRandoms);
                        }
                    }

                    //必须将所有设置为0
                    allDie = true;//再检测一次是否全灭了
                    for (FCPlayerBattleWrap wrap : fcv.getBattleWraps()) {
                        wrap.setBattlePlayerSelectMenu(-1);
                        wrap.setBattleReady(false);
                        wrap.setBattlePlayerSelectPlayer("");
                        wrap.setBattlePlayerSelectMonster(0);
                        wrap.setBattleUseItemType(-1);
                        wrap.setBattlePlayerSelectItem(-1);
                        wrap.setBattlePlayerSelectPaoDanIndex(-1);
                        wrap.setBattlePlayerSelectItemMode(-1);
                        //这里也会触发团灭死亡的
                        FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(wrap.getHostUid(), wrap.getName());
                        if (p != null && !wrap.getHostUid().equals("npc") && p.getBlood() > 0) {
                            allDie = false;
                        }
                    }
                    if (!allDie) {
                        fcv.setBattleReady(true);
                        fcv.setBattleAnimationNum(0);
                        fcv.setBattleHurtCount(false);

                        fcv.setBattleRounds(fcv.getBattleRounds() + 1);
                        defaultFightScreen.selectNextPlayer();
                        if (fcv.getBattleEvent() != null) {
                            eventOrderHelper.dealBattleEvent((BattleEvent) fcv.getBattleEvent(), fcv.getBattleRounds());
                        }
                    }

//                    try {
//                        Thread.sleep(800);
//                        fcv.getBattleResultText().clear();
//                    }catch (Exception e){}
                }

                if (allDie) {
                    //TODO
                    for (FCPlayerBattleWrap per : fcv.getBattleWraps()) {
                        FCPlayerInfo p = FCMutilPlayCache.findPlayerByName(per.getHostUid(), per.getName());
                        if (p != null && p.getPlayertank1() != null && !p.getPlayertank1().equals("null") && p.getAliasUID().equals(gameSave.HOST_UID)) {
                            gameSave.useTankOfPlayerId(p, p.getPlayertank1(), p.getPlayertankHostId());
                            //下车
                        }
                    }
                    fcv.getBattleAttackOrder().clear();
                    fcv.setBattleSummary(true);
                    fcv.setBattleHurtCount(false);
                    if (!fcv.isInTeamLink()) {
                        List<FCPlayerInfo> playerInfos = new ArrayList<>(1);
                        for (FCPlayerBattleWrap battleWrap : fcv.getBattleWraps()) {
                            FCPlayerInfo tp = FCMutilPlayCache.findPlayerByName(battleWrap.getHostUid(), battleWrap.getName());
                            if (tp != null) {
                                playerInfos.add(tp);
                            }
                        }
                        if (FCRMaster.fcv.isSever()) {
                            FCRSocketServer.getIn().syncPlayerState(playerInfos);
                        } else if (FCRMaster.fcv.isClient()) {
                            FCRSocketClient.getIn().syncPlayerState(playerInfos);
                        }

                        fcv.setPlayingEvent(eventLib.getEventOfName("WelcomeToMingQi"));
                        sound.setEffectSound(((JumpEvent) fcv.getPlayingEvent()).getMusicnum0());
                        fcv.setJumpactionnum(0);
                        //TODO 通知队友也要转场了
                        if (FCRMaster.fcv.isSever()) {
                            FCRSocketServer.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), ((JumpEvent) fcv.getPlayingEvent()).getDestination());
                        } else if (FCRMaster.fcv.isClient()) {
                            FCRSocketClient.getIn().playerJumpEvent(fcv.getPlayingEvent().getName(), ((JumpEvent) fcv.getPlayingEvent()).getDestination());
                        }
                        //TODO 送你去见明奇
                        startToSeeMingQi();
                    }

                } else {

                    //TODO 计算是否战斗结束
                    int surmonster = fcv.getBattleMonster().size();
                    for (FCMonster mon : fcv.getBattleMonster()) {
                        if (mon.getIsDeath())
                            surmonster--;
                    }
                    if (surmonster < 1 && fcv.getBattleMonster().size() > 0) {
                        //TODO怪物全死了
                        if (fcv.getBattleEvent() != null && fcv.getBattleBossRecord() != null) {
                            //TODO 剧情战斗判断的
                            gameSave.getBattleBossMaps().put(fcv.getBattleBossRecord().getKey(), fcv.getBattleBossRecord());
                            fcv.setBattleRounds(-1);
                            eventOrderHelper.dealBattleEvent((BattleEvent) fcv.getBattleEvent(), -1);

                            fcv.setBattleBossRecord(null);
                            fcv.setBattleEvent(null);
                            //TODO 如果有结尾对话，哪就要对话
                            //要存档
                            if (FCDataSingles.getWriter().writeSaveData(FCRMaster.player1, FCRMaster.gameSave, FCRMaster.gamedate, FCRMaster.tankLib)) {
                                FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_SUCCESS);
                            } else {
                                FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_FAILURE);
                            }
                            FCRMaster.fcv.showMessage();
                        }
                        fcv.setBattleSummary(true);
                        fcv.setBattleHurtCount(false);
                    }

                }
                if (fcv.getBattleAnimationNum() > 480) {
                    fcv.setBattleAnimationNum(0);
                }
            } else {
                if (fcv.isBattle()) {
                    if (fcv.getBattleSayText().size() > 0) {
                        //此刻在战斗剧情结对话中
                        return;
                    }
                    //有npc的指令
                    if (fcv.getNpcOrders().size() > 0) {
                        FCBattleOrder order = fcv.getNpcOrders().peek();
                        //order执行结束了
                        if (fcv.getBattleAnimationNum() > order.frameTimes) {
                            //TODO 主要是解析指令
                            eventOrderHelper.dealNpcMonsterBattleEventEnd(order, fcv.getBattleAnimationNum());
                            if (fcv.getNpcOrders().size() > 0) {
                                fcv.getNpcOrders().pop();
                            }
                            fcv.setBattleAnimationNum(-1);
                        } else {
                            //TODO 那就是这个指令需要渲染动画
                            eventOrderHelper.dealNpcMonsterBattleEvent(order, fcv.getBattleAnimationNum());
                        }
                        fcv.setBattleAnimationNum(fcv.getBattleAnimationNum() + 1);
                        //TODO 完全处理完NPC的指令
                        return;
                    }
                    //TODO npc和处理他们战斗准备
                    eventOrderHelper.findAllNpcAndReadyThem();
                    // 结算
                    if (fcv.isBattleSummary()) {
                        int moneyGet = 0;
                        ArrayList<String> dropItems = new ArrayList<>();
                        int allExp = 0;
                        Random random = new Random();
                        for (FCMonster monster : fcv.getBattleMonster()) {
                            if (monster.getIsDeath() && !monster.isEscapeState()) {
                                moneyGet += monster.getMoney();
                                allExp += monster.getExperience();
                                if (!monster.getDropItemID().equals("null") && random.nextFloat() <= monster.getDropPro()) {
                                    dropItems.add(monster.getDropItemID());
                                }

                                Integer killNum = gameSave.getFcMonsterKillRecordMap().get(monster.getName());
                                if (killNum == null) {
                                    killNum = 1;
                                } else {
                                    killNum += 1;
                                }
                                System.out.println("kill " + monster.getChName() + " count:" + killNum);
                                gameSave.getFcMonsterKillRecordMap().put(monster.getName(), killNum);
                            }
                        }

                        int delMoney = 0;
                        int allMoney = moneyGet;
                        if (gameSave.getFcZucheTankList().size() > 0) {
                            //TODO 有租车，钱不可能拿完的
                            moneyGet = (int) (moneyGet * 0.8);
                            delMoney = allMoney - moneyGet;
                        }
                        System.out.println("总结：击杀总经验" + allExp + "点，掉落金币" + allMoney + "G " + (delMoney == 0 ? "" : "扣除租车费" + delMoney + "G"));
                        fcv.endBattleInfo("总结：击杀总经验" + allExp + "点，掉落金币" + allMoney + "G " + (delMoney == 0 ? "" : "扣除租车费" + delMoney + "G"));
                        FCRMaster.fcv.getMessage().add("总结：击杀总经验" + allExp + "点，掉落金币" + allMoney + "G " + (delMoney == 0 ? "" : "扣除租车费" + delMoney + "G"));
                        FCRMaster.fcv.showMessage();

                        List<FCPlayerInfo> needSyncplayerInfos = new ArrayList<>(1);
                        for (FCPlayerBattleWrap battleWrap : fcv.getBattleWraps()) {
                            ArrayList<FCLongTermState> longTermStates = battleWrap.getRemainLongTermState();
                            FCPlayerInfo pl = FCMutilPlayCache.findPlayerByName(battleWrap.getHostUid(), battleWrap.getName());
                            if (pl != null) {
                                if (pl.isDeath() && pl.getPlayertank1() != null && !pl.getPlayertank1().equals("null") && pl.getAliasUID().equals(gameSave.HOST_UID)) {
                                    gameSave.useTankOfPlayerId(pl, pl.getPlayertank1(), pl.getPlayertankHostId());
                                    //下车
                                }
                                pl.getLongTermMap().clear();
                                for (FCLongTermState s : longTermStates) {
                                    pl.getLongTermMap().put(s.stateName, s);
                                }
                                if (allExp > 0 && pl.getAliasUID().equals(gameSave.HOST_UID)) {
                                    if (!pl.isDeath()) {//没死的可以拿经验
                                        boolean isUpLevel = pl.addExperience(allExp);
                                        if (isUpLevel) {
                                            fcv.endBattleInfo(pl.getChName() + "升级了 " + pl.getUpgradeData1());
                                            fcv.endBattleInfo("             " + pl.getUpgradeData2());
                                            FCRMaster.fcv.getMessage().add(pl.getChName() + "升级了 " + pl.getUpgradeData1());
                                            FCRMaster.fcv.getMessage().add("  " + pl.getUpgradeData2());
                                            FCRMaster.fcv.showMessage();
                                        }
                                    }
                                    needSyncplayerInfos.add(pl);
                                }
                            }
                        }
                        //本地人物获得钱
                        player1.setMoney(moneyGet + player1.getMoney());
                        for (String dropItem : dropItems) {
                            FCItem fItem = itemLib.getItemOfID(dropItem);
                            if (fItem != null) {

                                if (fItem.getCatalog().equals("tank")) {
                                    FCTank fcTank = tankLib.getTankOfID(player1.getPlayertank1(), player1.getPlayertankHostId());
                                    if (fcTank != null && fcTank.addItemToKnapsack(dropItem)) {

                                    } else {
                                        System.out.println("背包不足无法装下-" + fItem.getChName());
                                        fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + "背包不足无法装下-" + fItem.getChName());
                                        fcv.showMessage();
                                    }
                                } else {
                                    if (!player1.addItemToKnapsack(dropItem)) {
                                        System.out.println("背包不足无法装下-" + fItem.getChName());
                                        fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.BATTLE + "背包不足无法装下-" + fItem.getChName());
                                        fcv.showMessage();
                                    }
                                }
                                System.out.println("获得物品-" + fItem.getChName());
                                fcv.getMessage().add("获得物品-" + fItem.getChName());
                                fcv.showMessage();
                                fcv.endBattleInfo("获得物品-" + fItem.getChName());
                            }
                        }

                        try {
                            Thread.sleep(200);
                        } catch (Exception e) {
                        }

                        fcv.setBattleBossRecord(null);
                        fcv.setBattleEvent(null);
                        fcv.getBattleItem().clear();
                        fcv.getBattleAttackOrder().clear();
                        fcv.getBattleMonster().clear();
                        fcv.getBattleMonsterCoor().clear();
                        fcv.setBattleSummary(false);
                        fcv.setBattleEnd(true);
                        fcv.setBattleY(fcv.getBattleY() - 20);
                        fcv.setBattleExperience(0);
                        fcv.setBattlemoney(0);
                        FCMutilPlayCache.battleEnd();
                        fcv.getNpcOrders().clear();
                        fcv.getBattleResultText().clear();
                        //TODO 结束战斗后，以各自的队伍状态同步出去
                        //if (!fcv.isInTeamLink()) {

                        if (FCRMaster.fcv.isSever()) {
                            FCRSocketServer.getIn().syncPlayerState(needSyncplayerInfos);
                            FCRSocketServer.getIn().syncOthterPlayerTankStateAndItems();
                        } else if (FCRMaster.fcv.isClient()) {
                            FCRSocketClient.getIn().syncPlayerState(needSyncplayerInfos);
                            FCRSocketClient.getIn().syncOthterPlayerTankStateAndItems();
                        }
                        // }
                    } else {
                        boolean isAllReady = true;

                        fcv.setBattleAnimationNum(fcv.getBattleAnimationNum() + 1);
                        if (fcv.getBattleAnimationNum() == 100) {
                            for (FCPlayerBattleWrap wrap : fcv.getBattleWraps()) {
                                if (!FCPlayerBattleWrap.canThisBattle(wrap)) {
                                    wrap.setBattleReady(true);
                                    //TODO 不能战斗的自己ready
                                }
                            }
                        }
                        for (FCPlayerBattleWrap wrap : fcv.getBattleWraps()) {
                            FCPlayerInfo playerInfo = FCMutilPlayCache.findPlayerByName(wrap.getHostUid(), wrap.getName());
                            if (playerInfo != null && !playerInfo.isDeath() && !wrap.isBattleReady()) {
                                isAllReady = false;
                                break;
                            }
                        }
                        //   System.out.println(" "+fcv.getBattleWraps().size()+" "+isAllReady+" "+fcv.isBattleReady()+" "+fcv.getBattleAttackOrder().size());


                        if (!fcv.isBattleEnd() && fcv.getBattleWraps().size() > 0 && isAllReady && fcv.getBattleAttackOrder().size() == 0) {
                            ArrayList<FCBattleOrder> listOrder = new ArrayList<>();
                            fcv.getBattleAttackOrder().clear();
                            //装备的复位
                            fcv.setOpenMenu(false);
                            FCRMaster.fcv.setKnapsackItemNum(-1);
                            FCRMaster.fcv.setKnapsackItemName("null");
                            FCRMaster.fcv.setMoveKnapsackItem(false);

                            //TODO STEP 1 计算玩家的攻击
                            for (FCPlayerBattleWrap wrap : fcv.getBattleWraps()) {
                                FCPlayerInfo playerInfo = FCMutilPlayCache.findPlayerByName(wrap.getHostUid(), wrap.getName());
                                if (playerInfo != null && !playerInfo.isDeath() && FCPlayerBattleWrap.canThisBattle(wrap)) {
                                    listOrder.add(playerBattleOrderHelper.createPlayerBattleOrder(playerInfo, wrap));
                                }
                            }

                            //TODO STEP 2 计算怪物攻击对象
                            for (int i = 0; i < fcv.getBattleMonster().size(); i++) {
                                FCMonster sM = fcv.getBattleMonster().get(i);
                                if (!sM.getIsDeath()) {
                                    int attackTimes = (int) (sM.getAttackTimes());
                                    if ((sM.getAttackTimes() - attackTimes) > 0) {
                                        float newRand = fcv.getSingleRandom();
                                        if (newRand > 0.5) {
                                            attackTimes += 1;//经过判断还是加一次攻击
                                        }
                                    }
                                    for (int a = 0; a < attackTimes; a++) {
                                        listOrder.add(monsterBattleOrderHelper.createMonsterAttackOrder(sM, i));
                                    }
                                }
                            }
//                        System.out.println("排序前");
//                        for (FCBattleOrder o : listOrder) {
//                            System.out.println("排序  " + o.battleType + " " + o.battleSpeed + " " + o.monsterNum + " " + o.playerName);
//                        }
                            //TODO STEP 3 把指令按速度排序，速度一致时，优先让玩家在前
                            Comparator com = new Comparator<FCBattleOrder>() {
                                @Override
                                public int compare(FCBattleOrder o1, FCBattleOrder o2) {
                                    return o2.battleSpeed - o1.battleSpeed;
                                }
                            };
                            Collections.sort(listOrder, com);

//                        System.out.println("排序后");
//                        for (FCBattleOrder o : listOrder) {
//                            System.out.println("排序  " + o.battleType + " " + o.battleSpeed + " " + o.monsterNum + " " + o.playerName);
//                        }
                            //TODO STEP 4
                            fcv.getBattleAttackOrder().addAll(listOrder);
                            fcv.setBattleAnimationNum(0);
                            fcv.setBattleHurtCount(true);
                            fcv.setBattleReady(false);
                        }
                    }
                }
            }
        }
    }

    private HashMap<String, String> active = new HashMap<>();// 剧情当前步骤参数
    @Getter
    private boolean plotnpc1ismove = false;
    @Getter
    private int plotnpcactivenum = 0;

    // 剧情npc动作线程
    private class plotnpcactive extends TimerTask {

        @Override
        public void run() {
            if (fcv.getPlotiding1() != null && !fcv.isBattle()) {
                plotnpcactivenum++;
                if (!fcv.isPlotNpc1SayClick() && !plotnpc1ismove) {// 指令操作
                    //还要获取第一条指令，是否跳到那个地图，然后控制主角的xy位置，

                    // 获取当前动作参数
                    if (active.size() < 1) {
                        String[] qwe = plotLib.getActiveOfIdAndNum(fcv.getPlotiding1(), plotstep1).replaceAll(">\n", "")
                                .replaceAll(">", "").replaceAll("<", "plottype=").split(" ");
                        for (String k : qwe)
                            active.put(k.split("=")[0], k.split("=")[1]);
                    }
                    // 判断和执行操作
                    String plotType = active.get("plottype");
                    if (plotType.equals("spwan")) {
                        plotnpc1.add(active.get("npc"));
                        plotnpc1face.put(active.get("npc"), 0);
                        plotnpc1suozai.put(active.get("npc"),
                                new Integer[]{Integer.valueOf(active.get("x")), Integer.valueOf(active.get("y"))});
                        plotnpc1mubiao.put(active.get("npc"),
                                new Integer[]{Integer.valueOf(active.get("x")), Integer.valueOf(active.get("y"))});
                        plotnpc1pianyi.put(active.get("npc"), new Integer[]{0, 0});
                        plotnpc1active.put(active.get("npc"), 0);
                        if (active.containsKey("music"))
                            sound.setBackgroundMusic(Integer.valueOf(active.get("music")));
                    } else if (plotType.equals("seth")) {
                        plotnpc1face.replace(active.get("npc"), Integer.valueOf(active.get("dir")));
                    } else if (plotType.equals("say")) {
                        plotnpc1sayname = active.get("npc");
                        plotnpc1sayid = active.get("id");
                        fcv.setPlotNpc1SayClick(Boolean.valueOf(active.get("isclick")));
                    } else if (plotType.equals("goto")) {
                        plotnpc1mubiao.replace(active.get("npc"),
                                new Integer[]{Integer.valueOf(active.get("x")), Integer.valueOf(active.get("y"))});
                        if (active.containsKey("iswait")) {
                            if (active.get("iswait").equals("true"))
                                plotnpc1ismove = true;
                        }
                        if (active.containsKey("gospeed")) {
                            plotnpcGoSpeed.put(active.get("npc"), Integer.parseInt(active.get("gospeed")));
                        } else {
                            plotnpcGoSpeed.put(active.get("npc"), 1);
                        }
                    } else if (plotType.equals("death")) {
                        plotnpc1.remove(active.get("npc"));
                        plotnpc1face.remove(active.get("npc"));
                        plotnpc1mubiao.remove(active.get("npc"));
                        plotnpc1suozai.remove(active.get("npc"));
                        plotnpc1pianyi.remove(active.get("npc"));
                        plotnpc1sayid = null;
                        fcv.setPlotNpc1SayClick(false);
                        plotnpc1sayname = null;
                    } else if (plotType.equals("isend")) {
                        //<isend noSave=1>
                        fcv.setPlotJumpStep1(false);
                        String willSave = active.get("noSave");
                        if (willSave != null && willSave.equals("1")) {
                            //TODO 不要保存
                        } else {
                            gameSave.updatePlotIsEndOfId(fcv.getPlotiding1(), true);
                        }
                        fcv.setPlotiding1(null);
                        plotnpc1.clear();
                        plotnpc1active.clear();
                        plotnpc1face.clear();
                        plotnpc1mubiao.clear();
                        plotnpc1pianyi.clear();
                        plotnpc1sayid = null;
                        plotnpc1sayname = null;
                        plotnpc1suozai.clear();
                        System.out.println("剧情结束");
                    } else if (plotType.equals("jump")) {
                        //<jump jumpEvent=mingQi> 跳转地图到的事件 touchOffKey
                        String jumpEvent = active.get("jumpEvent");
                    } else if (plotType.equals("touchOffKey")) {
                        //<touchOffKey key=duckPlot value=1>  默认没的话是-1
                        if (active.containsKey("key")) {
                            gameSave.getPlotTouchOffKeyMaps().put(active.get("key"), active.get("value"));
                        }
                    }else if (plotType.equals("changeNpcEvent")) {
                        //<changeNpcEvent npc=duckPlot event=talktohim>  改变npc所带的事件id，一般是对话的
                        gameSave.getChangeNpcSays().put(active.get("npc"), active.get("event"));
                    } else if (plotType.equals("reborn")) {
                        //<reborn player=you> 只能复活主角了
                        if (active.get("player").equals("you")) {
                            player1.setBlood(player1.getBloodMax());
                            player1.getLongTermMap().clear();//清除所有状态
                            player1.setPhysicalnum(player1.getPhysical());//恢复体力

                            List<FCPlayerInfo> playerInfos = new ArrayList<>(1);
                            playerInfos.add(player1);
                            if (FCRMaster.fcv.isSever()) {
                                FCRSocketServer.getIn().syncPlayerState(playerInfos);
                            } else if (FCRMaster.fcv.isClient()) {
                                FCRSocketClient.getIn().syncPlayerState(playerInfos);
                            }
                        }
                    } else if (plotType.equals("sleep") || plotType.equals("wait")) {
                        //<sleep time=1000>停顿指令
                        int time = Integer.parseInt(active.get("time"));
                        try {
                            Thread.sleep(time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else if (plotType.equals("save")) {
                        //<save> 存档
                        if (FCDataSingles.getWriter().writeSaveData(FCRMaster.player1, FCRMaster.gameSave, FCRMaster.gamedate, FCRMaster.tankLib)) {
                            FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_SUCCESS);
                        } else {
                            FCRMaster.fcv.getMessage().add(FCRConstants.SYSTEM + FCRConstants.SAVE + FCRConstants.SAVE_FAILURE);
                        }
                        FCRMaster.fcv.showMessage();
                    } else if (plotType.equals("hideplace")) {
                        //<hideplace x=4 y=5 mapName=DongXue1-2> 隐藏放置物阻拦的指令,支持隐藏NPC的指令
                        gameSave.getOtherEventMaps().put(active.get("mapName") + "*" + active.get("x") + "*" + active.get("y"), "hideplace");
                    } else if (plotType.equals("showplace")) {
                        //<hideplace x=4 y=5 mapName=DongXue1-2> 显示放置物阻拦的指令,支持显示NPC的指令
                        gameSave.getOtherEventMaps().remove(active.get("mapName") + "*" + active.get("x") + "*" + active.get("y"));
                    } else if (plotType.equals("resetPlot")) {
                        //<resetPlot name=testplot> 重置剧情
                        gameSave.getPlotIsEnd().put(active.get("name"), false);
                    } else if (plotType.equals("addItem")) {
                        //<addItem item=baoShiJing>
                        if (player1.addItemToKnapsack(active.get("item"))) {
                            FCRMaster.fcv.getMessage().add("获得了新物品！");
                            FCRMaster.fcv.showMessage();
                        } else {
                            //TODO 放到保管npc处
                            FCRMaster.fcv.getMessage().add("背包不足将放到了保管npc处！");
                            FCRMaster.fcv.showMessage();
                            gameSave.getFcBankList().add(active.get("item"));
                        }
                    } else if (plotType.equals("delItem")) {
                        //<delItem item=baoShiJing>
                        player1.subItemKnapsack(active.get("item"));
                    } else if (plotType.equals("playAnimation")) {
                        //播放地图动画
                        FCMapAnimation mapAnimation = mapAnimationLibrary.getMapAnimationByName(active.get("id"));
                        if (mapAnimation != null) {
                            mapAnimation.resetAnimation();
                            mapAnimation.setVisiable(1);
                        }
                    }
                    active.clear();
                    plotstep1++;
                } else {// 剧情npc行为,0down,3up,1left,2right
                    boolean asd = false;
                    for (String name : plotnpc1) {
                        Integer[] a = plotnpc1mubiao.get(name);
                        Integer[] b = plotnpc1suozai.get(name);
                        Integer[] c = plotnpc1pianyi.get(name);
                        int plotMoveSpeed = 1;
                        if (plotnpcGoSpeed.containsKey(name)) {
                            plotMoveSpeed = plotnpcGoSpeed.get(name);
                        }
                        if ((a[0] != b[0] || a[1] != b[1]) || (a[0] == b[0] && a[1] == b[1]
                                && (Math.abs(c[0]) > fcv.getMapPngSize() / 8 || Math.abs(c[1]) > fcv.getMapPngSize() / 8))) {
                            if (a[0] != b[0] || a[1] != b[1]) {
                                if (a[0] > b[0])
                                    plotnpc1face.replace(name, 0);
                                if (a[0] < b[0])
                                    plotnpc1face.replace(name, 3);
                                if (a[1] > b[1])
                                    plotnpc1face.replace(name, 2);
                                if (a[1] < b[1])
                                    plotnpc1face.replace(name, 1);
                            } else {
                                if (c[0] > 0 && Math.abs(c[0]) < fcv.getMapPngSize() / 8)
                                    plotnpc1face.replace(name, 1);
                                if (c[0] < 0 && Math.abs(c[0]) < fcv.getMapPngSize() / 8)
                                    plotnpc1face.replace(name, 2);
                                if (c[1] > 0 && Math.abs(c[1]) < fcv.getMapPngSize() / 8)
                                    plotnpc1face.replace(name, 3);
                                if (c[1] < 0 && Math.abs(c[1]) < fcv.getMapPngSize() / 8)
                                    plotnpc1face.replace(name, 0);
                            }
                            if (plotnpc1face.get(name) == 0) {
                                c[1] = c[1] + plotMoveSpeed;
                                if (c[1] > fcv.getMapPngSize() / 2) {
                                    c[1] = -fcv.getMapPngSize() / 2;
                                    b[0] = b[0] + 1;
                                }
                            } else if (plotnpc1face.get(name) == 3) {
                                c[1] = c[1] - plotMoveSpeed;
                                if (c[1] < -fcv.getMapPngSize() / 2) {
                                    c[1] = fcv.getMapPngSize() / 2;
                                    b[0] = b[0] - 1;
                                }
                            } else if (plotnpc1face.get(name) == 1) {
                                c[0] = c[0] - plotMoveSpeed;
                                if (c[0] < -fcv.getMapPngSize() / 2) {
                                    c[0] = fcv.getMapPngSize() / 2;
                                    b[1] = b[1] - 1;
                                }
                            } else if (plotnpc1face.get(name) == 2) {
                                c[0] = c[0] + plotMoveSpeed;
                                if (c[0] > fcv.getMapPngSize() / 2) {
                                    c[0] = -fcv.getMapPngSize() / 2;
                                    b[1] = b[1] + 1;
                                }
                            }
                            if (plotnpcactivenum > 8) {
                                plotnpcactivenum = 0;
                                plotnpc1active.replace(name,
                                        ((plotnpc1active.get(name) + 1 > 3) ? 0 : plotnpc1active.get(name) + 1));
                            }
                            asd = true;
                            plotnpc1mubiao.replace(name, a);
                            plotnpc1suozai.replace(name, b);
                            plotnpc1pianyi.replace(name, c);
                        }
                    }
                    plotnpc1ismove = asd;
                }
            }
        }
    }

    //TODO 强行直接进入剧情，比如人物团灭明奇，或者是一些事件携带触发得剧情id，都在这里触发
    public void forceStartPlot(String plotId) {
        synchronized (mLock) {
            fcv.setPlotiding1(plotId);
            if (fcv.getPlotiding1() != null) {
                plotstep1 = 0;
                plotnpc1.clear();
                fcv.setPlotJumpStep1(true);
                active.clear();
            }
        }
    }

    // 检测剧情事件触发线程
    private class touchoffplot extends TimerTask {
        @Override
        public void run() {
            synchronized (mLock) {
                if (fcv.getInterfacenum() == 5) {
                    if (plot == null) {
                        if (plotLib.getPlotNum() > 0 && fcv.getSaveUploadIsOk() == 1) {
                            plot = new FCPlotDetect(plotLib.getPlotID(), plotLib.getPlotTouoff(), gameSave.getPlotIsEnd());
                        }
                    } else {
                        plot.setplayer(gameSave.getPlotIsEnd());

                        if (fcv.getPlotiding1() == null) {
                            fcv.setPlotiding1(plot.isTriggerPlotOneplayer());
                            if (fcv.getPlotiding1() != null) {
                                plotstep1 = 0;
                                plotnpc1.clear();
                                fcv.setPlotJumpStep1(true);
                                active.clear();
                            }
                        }
                    }
                }
            }
        }

    }


    /**
     * 根据id获取战车的dir
     *
     * @param id
     * @return
     */
    public int getTankDirOfIDNum(int id) {
        switch (id) {
            case 1:
                return 1;
            default:
                return 0;
        }
    }


    public void startUpdataNPCActive() {
        new Timer().schedule(new updataNPCActive(), new Date(), 100);
        follRunMapAnimation.run();
    }

    public void startToSeeMingQi() {
        Schedulers.io().scheduleDirect(startToSeeMingQi, 200, TimeUnit.MILLISECONDS);
    }

    private Runnable startToSeeMingQi = new Runnable() {
        @Override
        public void run() {
            if (player1.getMapname().equals("LaDuo-MingQi")) {
                //TODO 送你去见明奇
                forceStartPlot("welcomeTomingQi");
            } else {
                Schedulers.io().scheduleDirect(startToSeeMingQi, 100, TimeUnit.MILLISECONDS);
            }
        }
    };

    private Runnable follRunMapAnimation = new Runnable() {
        HashMap<String, Integer> rhashMap = new HashMap<>();

        @Override
        public void run() {
            //控制地图动画动起来
            FCMap fcMap = mapLib.getMapOfName(player1.getMapname());
            if (fcMap != null) {
                int startX = player1.getPlayer1CoorX() - 9;
                int startY = player1.getPlayer1CoorY() - 16;
                if (fcMap.getMapAnimation().size() > 0) {
                    Iterator<Map.Entry<String, String>> iterator = fcMap.getMapAnimation().entrySet().iterator();
                    rhashMap.clear();
                    while (iterator.hasNext()) {
                        Map.Entry<String, String> entry = iterator.next();
                        String[] strings = entry.getKey().split("\\*");
                        int[] xy = new int[]{Integer.parseInt(strings[0]), Integer.parseInt(strings[1])};
                        if (xy[0] >= startX && xy[0] <= (startX + 18)
                                && xy[1] >= startY && xy[1] <= (startY + 32)) {
                            FCMapAnimation animation = mapAnimationLibrary.getMapAnimationByName(entry.getValue());
                            if (animation != null && animation.getVisiable() == 1 && !rhashMap.containsKey(entry.getValue())) {
                                animation.triggleChange();
                                rhashMap.put(entry.getValue(), 1);
                            }
                        }
                    }
                }
                if (fcMap.getDynamicMapAnimation().size() > 0) {
                    Iterator<Map.Entry<String, String>> iterator = fcMap.getDynamicMapAnimation().entrySet().iterator();
                    rhashMap.clear();
                    while (iterator.hasNext()) {
                        Map.Entry<String, String> entry = iterator.next();
                        String[] strings = entry.getValue().split("\\*");
                        int[] xy = new int[]{Integer.parseInt(strings[0]), Integer.parseInt(strings[1])};
                        if (xy[0] >= startX && xy[0] <= (startX + 18)
                                && xy[1] >= startY && xy[1] <= (startY + 32)) {
                            FCMapAnimation animation = mapAnimationLibrary.getMapAnimationByName(entry.getKey());
                            if (animation != null && animation.getVisiable() == 1 && !rhashMap.containsKey(entry.getKey())) {
                                animation.triggleChange();
                                rhashMap.put(entry.getKey(), 1);
                            }
                        }
                    }
                }
            }
            Schedulers.io().scheduleDirect(follRunMapAnimation, 80, TimeUnit.MILLISECONDS);
        }
    };

    //TODO 控制角色向前平滑快速移动多少格
    public void slideMoveNDistance(int n) {
        slideMoveNDistanceWithDir(n, player1.getActionDir());
    }

    public void slideMoveNDistanceWithDir(int n, int dir) {
        n = Math.abs(n);

        if (dir == 2) {
            fcv.setSlideTargetMapX(player1.getPlayer1x());
            fcv.setSlideTargetMapY(player1.getPlayer1y() + n);
        } else if (dir == 1) {
            fcv.setSlideTargetMapX(player1.getPlayer1x());
            fcv.setSlideTargetMapY(player1.getPlayer1y() - n);
        } else if (dir == 3) {
            fcv.setSlideTargetMapX(player1.getPlayer1x() - n);
            fcv.setSlideTargetMapY(player1.getPlayer1y());
        } else if (dir == 0) {
            fcv.setSlideTargetMapX(player1.getPlayer1x() + n);
            fcv.setSlideTargetMapY(player1.getPlayer1y());
        } else {

        }
        if (!fcv.isSliding()) {
            fcv.setSlideDir(dir);
            fcv.setSliding(true);
            FCRMaster.gameSave.perV = 15;
        }
    }
}
